'use strict';

const Service = require('egg').Service;
const sequelize = require('sequelize').Sequelize;
const Op = sequelize.Op;
const pinyin = require("pinyin");

class TypeService extends Service {

    async add(request) {
        let { type } = request;
        const { BookType } = this.ctx.model;

        const typeEx = await BookType.findOne({
            where: {
                type
            }
        });

        if (typeEx) { this.ctx.throw(400, "当前类型已存在！"); }

        let bookType = {
            type,
            createDate: new Date(),
            createBy: this.ctx.state.user.id
        }

        const retBookType = await BookType.create(bookType);

        return {
            result: true
        }
    }

    async tree() {
        const { BookType } = this.ctx.model;

        const types = await BookType.findAll();
        let baseTree = {};
        types.forEach(item => {
            let letter = pinyin(item.type, { style: pinyin.STYLE_FIRST_LETTER })[0][0];
            baseTree[`${letter}_${item.id}_${item.type}`] = 0;
        });

        const { id, type, name, isbn, recommended, description, publishingHouse } = this.ctx.query;

        let sql = 'SELECT b.id, t.id typeId, t.type FROM book b '
        sql += 'left join book_type t on b.type = t.id where';
        if (type) sql += ` t.type like '%${type}%' `;
        if (id) sql += ` ${type ? ' and ' : ''} b.id = ${id} `;
        if (name) sql += ` ${type ? ' and ' : ''} b.name like '%${name}%' `;
        if (isbn) sql += ` ${type ? ' and ' : ''} b.isbn like '%${isbn}%' `;
        if (recommended) sql += ` ${type ? ' and ' : ''} b.recommended = ${recommended}`;
        if (publishingHouse) sql += ` ${type ? ' and ' : ''} b.publishing_house like '%${publishingHouse}%'`;
        if (description) sql += ` ${type ? ' and ' : ''} b.description like '%${description}%'`;
        if (!type && !id && !name && !isbn && !recommended && !publishingHouse && !description) sql = sql.replace('where', '')

        const typeInfos = await this.ctx.model.query(sql, { type: sequelize.QueryTypes.SELECT });
        for(let item of typeInfos) {
            let letter = pinyin(item.type, { style: pinyin.STYLE_FIRST_LETTER })[0][0];
            baseTree[`${letter}_${item.typeId}_${item.type}`]++;
        }
        let letterObj = {}
        let summary = {};
        Object.keys(baseTree).forEach(item => {
            let key = item.split('_');
            letterObj[key[0]] = []
            if(!summary[key[0]])summary[key[0]]=0;
            summary[key[0]]+=baseTree[item];
            letterObj[key[0]].push({ id: key[1], group: `${key[2]} (${baseTree[item]})`})
        })
        let tree = []
        Object.keys(letterObj).forEach(key => {
            tree.push({
                group: `${key} (${summary[key]})`,
                child: letterObj[key]
            })
        })


        tree = tree.sort(function (a, b) { return a.group.charCodeAt(0) - b.group.charCodeAt(0) });

        return {
            tree
        };
    }

    async list(pageNo, pageSize, filter) {
        const { BookType } = this.ctx.model;

        const offset = pageSize * (pageNo - 1);
        const limit = pageSize;
        const order = [["create_date", "desc"]];

        const attributes = [
            ["id", "id"],
            ["type", "type"],
            ["create_date", "createDate"]
        ];

        const bookTypes = await BookType.findAndCountAll({
            where: filter, attributes, limit, offset, order
        });

        let hasNextPage = pageNo * pageSize < bookTypes.count;

        let result = {
            totalCount: bookTypes.count,
            pageNo,
            pageSize,
            types: bookTypes.rows,
            hasNextPage,
        };

        return result;
    }

    async update(request) {
        const { BookType } = this.ctx.model;
        let bookType = await BookType.findOne({
            where: {
                id: request.id
            }
        });

        if (!bookType) {
            this.ctx.throw(404, '类型不存在！')
        }

        bookType.type = request.type;
        bookType.updateDate = new Date();
        bookType.updateBy = this.ctx.state.user.id;
        await bookType.save();

        return {
            result: true
        };

    }

    async delete(id) {
        const { BookType, Book } = this.ctx.model;
        let bookType = await BookType.findOne({
            where: {
                id
            }
        });

        if (!bookType) {
            this.ctx.throw(404, '类型不存在！')
        }

        const book = await Book.findOne({
            where: {
                [Op.and]: {
                    type: id,
                    onSale: {
                        [Op.ne]: 1,
                    }
                }
            }
        });

        if (book) {
            this.ctx.throw(400, '当前类型存在书籍，删除失败！')
        }
        await BookType.destroy({
            where: {
                id
            }
        });

        return {
            result: true
        };

    }
}
module.exports = TypeService;
